% \iffalse meta-comment ---------------------------------------------
% Copyright (C) Shanghai Jiao Tong University
% The definition in this file is referred to the Visual Identity System
% from Shanghai Jiao Tong University (SJTU). 
% See https://vi.sjtu.edu.cn for more information.
% 
% SJTUG implements the design but doesn't hold the copyright.
% Any commercial usage in this file should be acknowledged by
% the administration of SJTU.
% More information about the license,
% see https://vi.sjtu.edu.cn/index.php/articles/bulletin/16. 
% ------------------------------------------------------------------- \fi
% \iffalse
%<*package>
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sjtuvi}[2023/11/25 v3.0.1 Visual Identity System library for sjtubeamer]
%</package>
% \fi
% \CheckSum{0}
% \StopEventually{}
% \iffalse
%<*package>
% ------------------------------------------------------------------- \fi
%
% \subsection{SJTU VI Library}
% This library provides the definition of basic elements in SJTU VI,
% including color, logo and some shapes. 
%
% \subsubsection{Variable Declarations}
%
% Special variables will be declared globally.
% These macros are only used internally.
%
% \begin{macro}{\ifsjtubeamer@tempif}
% \verb"\ifsjtubeamer@tempif" is for
% customized condition tests ---
% \verb"\EqualOption" and \verb"\IsEmpty".
%    \begin{macrocode}
\newif\ifsjtubeamer@tempif%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sjtubeamer@tempbox}
% \verb"\sjtubeamer@tempbox" is for
% \verb"\IsEmpty" to detect the width of
% the paramter.
%    \begin{macrocode}
\newbox\sjtubeamer@tempbox%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sjtubeamer@h}
% \verb"\sjtubeamer@h" is for
% \verb"\stamptext" to measure the height
% of the parameter.
%    \begin{macrocode}
\newskip\sjtubeamer@h%
%    \end{macrocode}
% \end{macro}
%
%
% \subsubsection{Utilities}
%
% \begin{macro}{\DefineOption}
% Define the beamer option on the
% corresponding package, key and value.
%    \begin{macrocode}
\def\DefineOption#1#2#3{%
  % #1: package
  % #2: key
  % #3: value
  \DeclareOptionBeamer{#3}{\expandafter\def\csname sjtubeamer@#1@#2\endcsname{#3}}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\EqualOption}
% To check if the option on package,
% key is equal to value.
%
% \verb"\if\EqualOption{<package>}{<key>}{<value>}<action>\fi"
%    \begin{macrocode}
\def\EqualOption{TT\fi\ifEqualOption}
\def\ifEqualOption#1#2#3{%
  % #1: package
  % #2: key
  % #3: value
  \edef\tempvar{\csname sjtubeamer@#1@#2\endcsname}%
  \def\tempvalue{#3}%
  \ifx\tempvar\tempvalue\sjtubeamer@tempiftrue\else\sjtubeamer@tempiffalse\fi%
  \ifsjtubeamer@tempif%
}
%    \end{macrocode}
% Here, a dummy trick is used to pass the if condition, inspired by
% \url{https://tex.stackexchange.com/a/117190/253485}.
% \verb"\EqualOption" is the interface to use, while \verb"\ifEqualOption" is
% the internal macro.
%
% Since \LaTeX\ handles \verb"\if" differently.
% \verb"\iftrue" will eliminate the nearest \verb"\else" and \verb"\fi"
% but remains other extra \verb"\fi" and throws errors.
%
% To avoid this, if the macro is expanded after \verb"\if", \verb"T=T",
% the condition holds and finish the current pair.
% And continues to process the real defined macro.
% This solution is somehow to combat against the \LaTeX\ compiler.
% In modern \LaTeX3, it is not so nasty to deal with neseted conditions.
%
% \verb"\iffalse" doesn't need to be considered.
%
% NOTICE: the line-end \verb"%" is necessary, otherwise the eaten space or some
% errors could occur.
% \end{macro}
%
% \begin{macro}{\IsEmpty}
% To check the expanded parameter is empty
% based on the box width. \verb"\\" will be
% treated as empty.
%
% \verb"\if\IsEmpty{<test>}<action>\fi"
%    \begin{macrocode}
\def\IsEmpty{TT\fi\ifIsEmpty}
\def\ifIsEmpty#1{%
  \setbox\sjtubeamer@tempbox=\hbox\bgroup\def\\{}#1\unskip\egroup%
  \ifdim\wd\sjtubeamer@tempbox=0pt \sjtubeamer@tempiftrue%
  \else\sjtubeamer@tempiffalse\fi%
  \ifsjtubeamer@tempif%
}
%    \end{macrocode}
% Almost the same as \verb"\EqualOption" construction.
% You should use the macro \verb"\IsEmpty" instead of \verb"\ifIsEmpty" directly
% to avoid the error from nested condition tests.
%
% Even though there are \verb"\ifdefempty" and \verb"\ifdefvoid" in package
% \verb"etoolbox", they are not capable of judging the expanded empty macros,
% i.e., if you define \verb"\def\aaa{\bbb}" while \verb"\def\bbb{}",
% \verb"\ifdefempty{\aaa}" will return false even though its expanded version is empty.
%
% Originally, we use \verb"\ifx\insertinstitute\@empty" when the macro is not
% abstracted, as it has been done in beamer class. But it doesn't work here with
% the same issue above. Because macros like \verb"\insertinstitute" are global states:
% When the user set \verb"\institute[]{}", it will check if the paramter is empty,
% and if it is, \verb"\def\insertinstitute{}" will be manually set without any
% nested macros.
% Unfortunately, as an independent macro, the paramter should not be limited to
% certain scenarios.
%
% This macro is inspired by \url{https://tex.stackexchange.com/a/53091/253485},
% we could typeset the macro out and determine whether it is empty by its box width.
% Like \verb"\beamer@setupshort" in beamer class, redefine \verb"\\" to nothing
% in the condition test, since it cannot show up in the horizontal mode and shoule
% be treated as an empty charater. \verb"\unskip" here will treat all trailing
% spaces as empty in case that macro forgets to insert the trailing \verb"%"
% and has breaklines, which is not intended.
%
% As the basic primitive for \TeX{}, \verb"\if\aaa\@empty" itself could be used
% instead of \verb"\ifx". But the side effect of this is that your paramter
% should not be expanded to \verb"\\". Macros like \verb"\insertinstitute",
% as mentioned, has used \verb"\beamer@setupshort" to detect the corner case
% \verb"\\" in the macro.
%
% We want this package to be independent from beamer class, so a manually
% defined macro could be better and this will treat the empty spaces to empty.
% \end{macro}
%
% \begin{macro}{\getcontribdir}
% Get the contrib directory for \verb"#1"
% sub-theme.
% \verb"contrib/#1" is returned.
%    \begin{macrocode}
\providecommand{\getcontribdir}[1]{contrib/#1}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\getcontribpath}
% Get the contrib directory filepath for
% \verb"#1" sub-theme and \verb"#2" filename.
% \verb"contrib/#1/#2" is returned.
%    \begin{macrocode}
\providecommand{\getcontribpath}[2]{\getcontribdir{#1}/#2}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Load TikZ}
% Load TikZ package and its related library: 
% \begin{itemize}
%   \item \verb"pattern.meta" provides the interface to define a pattern; 
%   \item \verb"fadings" provides the method to create a fading mask;
%   \item \verb"decoration.pathmorphing" provides the interface to user-define
%         a decoration.
%   \item \verb"external" provides the way for tikz externalization, which will
%         reduce the number of repetitive rendering with the cached pdf.
%   \item \verb"backgrounds" provides the way to make a scope as a background
%         to draw later.
% \end{itemize}
%    \begin{macrocode}
\RequirePackage{tikz}
\usetikzlibrary{fadings}
\usetikzlibrary{decorations.pathmorphing}
\usetikzlibrary{external}
\usetikzlibrary{backgrounds}
%    \end{macrocode}
%
% \subsubsection{Color Definition}
% The following color is defined by SJTU VI.
% \begin{description}
%   \item[primary] The primary color, which influences the color of title and the
%                  background of title page.
%   \item[secondary] The secondary color, which influences the color of subtitle.
%   \item[tertiary] The tertiary color, which provides the color for the blocks.
% \end{description}
%    \begin{macrocode}
\definecolor{sjtuRedPrimary}{RGB}{167,32,56}         % engred
\definecolor{sjtuRedSecondary}{RGB}{240,131,0}       % orange
\definecolor{sjtuRedTertiary}{RGB}{253,208,0}        % yellow
\definecolor{sjtuBluePrimary}{RGB}{0,64,152}         % problue 
\definecolor{sjtuBlueSecondary}{RGB}{51,141,39}      % lightgreen
\definecolor{sjtuBlueTertiary}{RGB}{0,81,78}         % lightgray
%    \end{macrocode}
%
% \subsubsection{Declare Logo}
% Aquire package \verb"array" for better control on \verb"tabular".
%    \begin{macrocode}
\RequirePackage{array}
%    \end{macrocode}
%
% \begin{macro}{\definelogo}
% Define a mask picture to make its
% different color variants.
%
% The first argument is the control
% sequence name of the generated command,
% without the backslash.
%
% The second argument assigns the path to
% the logo file.
%
% The third argument sets the horizontal
% cropping. Range from 0 to 1.
%
% The fourth argument sets the vertical
% cropping. Range from 0 to 1.
%
% Notice that the cropping is
% symmetrical (double the length).
% When the horizontal cropping is greater
% than the vertical cropping, the mask
% will be placed by its height, otherwise
% by its width.
%
% You should define a logo
% \verb"\definelogo{mylogo}{path}{<hc>}{<vc>}"
% then use it in the contents like:
% \verb"\mylogo[white]",
% where the optional parameter could be
% the override color beyond the control of
% main logo color system or
% \verb"opacity=..."
% to identify the opacity you want or any
% other parameter for a TikZ node.
%
% The externalization will be disabled
% when using this system to generate
% logos, locally.
%    \begin{macrocode}
\newcommand{\definelogo}[4]{
  % #1: csname
  % #2: path
  % #3: horizontal clip (0~1)
  % #4: vertical clip (0~1)
  \pgfmathparse{notgreater(#3,#4)}
  \ifnum\pgfmathresult=1
    \begin{tikzfadingfrompicture}[name=#1]
      \fill[black] (-1,-1) rectangle (1,1);
      \node {\includegraphics[width=1.5cm]{#2}};
    \end{tikzfadingfrompicture}
  \else 
    \begin{tikzfadingfrompicture}[name=#1]
      \fill[black] (-1,-1) rectangle (1,1);
      \node {\includegraphics[height=1.5cm]{#2}};
    \end{tikzfadingfrompicture}
  \fi
  \expandafter\providecommand\csname #1\endcsname[1][]{%
    % ##1: override color, or opacity=... (optional)
    \tikzexternaldisable%
    \begin{tikzpicture}
      \begin{scope}
        \clip ({-1.0+#3},{-1.0+#4}) rectangle ({1.0-#3},{1.0-#4});
        \fill [##1, path fading=#1] (-1,-1) rectangle (1,1);
      \end{scope}
    \end{tikzpicture}%
  }
}
%    \end{macrocode}
% WARNING: When using \verb"\resizebox" or in some boxes, the end of the line
% will be treated as a space according to the \LaTeX{} rule, which may cause
% extra space when measuring the object.
%
% Use \verb"%" symbol at the end of the line to avoid the unwanted space, which
% is recommended to all lines in the command or the start and the end of the outer environment.
%
% TODO: add the feature to insert a logo with or without the safe spacing (1/5h).
%
% \changes{v3.0.0}{2022/11/25}{changed the first two arguments from \oarg{folder}\marg{file}
% to \marg{csname}\marg{path}.}
% \end{macro}
%
% Define the required logo.
%    \begin{macrocode}
\definelogo{sjtubadge}{vi/sjtu-vi-sjtubadge.pdf}{0}{0}
\definelogo{zhlogo}{vi/sjtu-vi-zhlogo.pdf}{0.13}{0.75}
\definelogo{enlogo}{vi/sjtu-vi-enlogo.pdf}{0.13}{0.75}
\definelogo{dlogo}{vi/sjtu-vi-dlogo.pdf}{0}{0}
\definelogo{vlogo}{vi/sjtu-vi-vlogo.pdf}{0.8}{0.13}
\definelogo{sjtubg}{vi/sjtu-vi-sjtubg.png}{0.3}{0.5}
\definelogo{sjtugate}{vi/sjtu-vi-sjtugate.png}{0.25}{0.8}
%    \end{macrocode}
%
% \begin{macro}{\secondaryinstlogo}
% Logo with secondary institute.
%
% The first optional parameter is
% typically the English name for your
% institute.
% If it exists (Chinese style), will be
% typesetted below the main name.
% THERE SHOULD BE NO \verb"\\".
%
% The second mandantory parameter is the
% main name for your institute.
% When the optional paramter is empty
% (English style),
% YOU COULD USE \verb"\\" as linebreaks.
%
% The third parameter is the logo on the
% left side, you could leave it as empty
% but it is mandantory.
%
% When it is in English style
% (no optional parameter),
% you could use a secondary logo picture
% as your institute, but remember to
% resize the height to 0.95cm.
%    \begin{macrocode}
\newcommand{\secondaryinstlogo}[3][]{%
  % #1: shortinst (optional)
  % #2: longinst
  % #3: logo
%    \end{macrocode}
% Start a hbox as a container. 
% Remember the end of the line will be treated as a space in the paramter of \verb"hbox"
% (which is a \TeX{} primitive). To avoid that, add a \verb"%" at the end of the line.
%    \begin{macrocode}
  \hbox{%
%    \end{macrocode}
% Make sure the content is left aligned.
%    \begin{macrocode}
    \raggedright%
%    \end{macrocode}
% Insert the resized logo. The empty logo is supported as we insert \verb"\vphantom" here.
%    \begin{macrocode}
    \resizebox{!}{1cm}{\vphantom{-}#3}%
    \if\IsEmpty{#2}%
%    \end{macrocode}
% If the long institute name is empty the right part will not be typesetted.
%    \begin{macrocode}
    \else%
      \if\IsEmpty{#1}%
%    \end{macrocode}
% If the short institute is empty, the English version of the combined logo will be configured.
% The margin around the vrule is 0.31cm in this manner.
%    \begin{macrocode}
        \if\IsEmpty{#3}\else%
          {\hskip0.31cm\vrule width0.5pt}\hskip0.31cm%
        \fi%
%    \end{macrocode}
% You need to manually break the line for the main English name.
% The whole name will be typesetted centered vertically.
%    \begin{macrocode}
        \vbox to 1cm{%
          \vfill%
%    \end{macrocode}
% Start a \verb"\hbox" inside the \verb"\vbox" to make sure that the box has a
% width that matches the content.
%    \begin{macrocode}
          \hbox{%
%    \end{macrocode}
% Since \verb"\scshape" may not contain the boldface font weight, we manually set
% the font weight to \verb"\mdseries" to avoid the influence from the outside.
%
% And there is no explicit rule about the font size of the English institute.
% Choose a similar one for approporiate look.
%    \begin{macrocode}
            \noindent%
            \fontsize{7pt}{0pt}\selectfont\mdseries\scshape%
%    \end{macrocode}
% Since the parameter could contain the breaklines \verb"\\", which is not
% functional in the horizontal mode. To make the thing work, wrap it into the
% \verb"tabular" environment, and remove the left-right padding by \verb"@{}".
% Then the paramter could break lines.
%
% To increase the interlineskip in tabular, use a phantom vrule at the end of
% each line with the depth of 2pt. At the end of the tabular, we should decrease
% the vskip by 2pt since the last line should not have that depth to make sure
% the content is vertically centered.
%    \begin{macrocode}
            \begin{tabular}{@{}l<{\vphantom{\vrule depth2pt}}@{}}
              #2
            \end{tabular}%
          }%
          \vskip-2pt%
%    \end{macrocode}
% In this way, the behavior like textbox in MS Word could be achieved, with the
% combination of \verb"\hbox" and \verb"tabular" environment, to make sure the
% bounding box could be measured and the content could use normal \verb"\\" for
% breaking lines. But \verb"\par" is not acceptable so you should use the
% hard-breaking in the command parameter.
% If \verb"p{}" is used for enabling the \verb"\par", the width can not be
% automatically calculated and always be the specified width.
%
% But the benefit is also obvious, the width could be controlled and no more
% overfull hbox when inserting the institute.
% Since a \verb"\vbox" without \verb"\hsize" will make a box that occupy the
% whole line, but the width of the box should not be limited inexplicitly
% (no rule in SJTU VI).
% Futhermore, An alternative of using \verb"\parbox" has the same issue.
%    \begin{macrocode}
          \vfill%
        }%
      \else%
%    \end{macrocode}
% If the short institute name is not empty, the short name will be typesetted below the long name.
% The margin around the vrule is 0.23cm in this manner.
%    \begin{macrocode}
        \if\IsEmpty{#3}\else%
          {\hskip0.23cm\vrule width0.5pt}\hskip0.23cm%
        \fi%
        \vbox to 1cm{%
%    \end{macrocode}
% Since \verb"\\" is not allowed in \verb"hbox", all the breaklines will be
% treated as empty in this mode. This will force the content output as a single line.
% The setting is mainly for some precautious reasons (it will lead some errors if not)
% and matching the behavior from the beamer class.
%    \begin{macrocode}
          \def\\{}%
%    \end{macrocode}
% Align the institute component to the bottom of the current vbox.
% And remove the interlineskip for precise measurement.
%    \begin{macrocode}
          \vfill
          \offinterlineskip
%    \end{macrocode}
% Use \verb"\hbox" to make sure the width of the box is measurable.
% \verb"\mdseries" will make sure that the font weight will not be influenced by
% the current configuration.
%    \begin{macrocode}
          \hbox{%
            \fontsize{13pt}{0pt}\selectfont%
            \mdseries\sffamily #2%
          }
%    \end{macrocode}
% A thin space between the line is inserted.
%    \begin{macrocode}
          \vskip0.08cm%
          \hbox{%
            \fontsize{5pt}{0pt}\selectfont%
            \mdseries\scshape #1%
          }
%    \end{macrocode}
% \verb"\prevdepth" is used to reduce the bottom padding by the depth of the
% previous line in case that the line has a comma.
%    \begin{macrocode}
          \vskip-\prevdepth\vskip0.14cm%
        }%
      \fi%
    \fi%
  }%
}
%    \end{macrocode}
% NOTE: This macro is not defined in ``star'' form, but the paramter could have
% linebreaks \verb"\\" but no \verb"\par". When another alternative --- could
% accept \verb"\par" --- comes up, the macro will be redefined in ``star'' form.
%
% For the optional parameter, \verb"\insertshortinsititute" in beamer class will
% first call \verb"\beamer@setupshort" to locally redefine \verb"\\" to empty,
% then the inserted text will not contain the breaklines.
% To insert the version with the breaklines, \verb"\beamer@shortinstitute" should be used.
%
% It is still recommended to use \verb"\institute" directly when it will lead to
% this combination logo. Since the form of the paramter could be more unified in
% the optional paramter where you could always keep the breaklines \verb"\\".
% In this parameter, you could not keep breaklines \verb"\\" if you pass an
% optional parameter. i.e., anything that violates the SJTU VI rule in this
% command will turn into an error.
%
% And if you insert a picture as the secondary institute as the main parameter,
% resize it to a 0.95cm height one for vertical alignment. i.e.,
% \verb"\resizebox{!}{0.95cm}{<pic>}".
% \end{macro}
%
% \subsubsection{Shape Declarations}
%
% \begin{macro}{\stamptext}
% Use one Chinese character or at most two
% English characters for the text
% argument.
%
% Make a stamp unit surround the text.
% Similar to \verb"\highlight" command in
% inner theme with limitations on number
% of characters.
% 
% Use an optional argument to set the
% background color, default is
% \verb"structure" or \verb"sjtuRedPrimary".
%    \begin{macrocode}
\providecommand{\stamptext}[2][structure]{
  {
%    \end{macrocode}
% If the color is not defined, it will fallback to color \verb"sjtuRedPrimary"
% in this pacakge. Notice if your color is not defined, it will not get an error
% through this manner.
%    \begin{macrocode}
    \providecolor{#1}{named}{sjtuRedPrimary}
%    \end{macrocode}
% Disable caching in this group.
%    \begin{macrocode}
    \tikzset{external/export=false}
    \begin{tikzpicture}[baseline=(nodetext.base)]
      \node [white] (nodetext) at (0,0) {#2};
%    \end{macrocode}
% Get the height of a tikz node \verb"nodetext" and store it in length \verb"\s".
% It is similar to \verb"\tcbsetmacroheightofnode" from \verb"skins" library of
% \verb"tcolorbox", but for decoupling reasons, use a native pgf command to calculate
% that without loading \verb"tcolorbox" in this style file.
%    \begin{macrocode}
      \pgfextracty{\sjtubeamer@h}{\pgfpointanchor{nodetext}{north}}%
      \pgfextracty{\pgf@ya}{\pgfpointanchor{nodetext}{south}}%
      \addtolength{\sjtubeamer@h}{-\pgf@ya}
%    \end{macrocode}
% Use a scope with \verb"on background layer" to adjust the order of rendering.
%    \begin{macrocode}
      \scoped[on background layer]
        \fill [#1]
          (-1.25*\sjtubeamer@h,0)
          -- (-0.85*\sjtubeamer@h,0.3*\sjtubeamer@h)
          -- (-0.85*\sjtubeamer@h,0.5*\sjtubeamer@h)
          -- (0.85*\sjtubeamer@h,0.5*\sjtubeamer@h)
          -- (0.85*\sjtubeamer@h,0.3*\sjtubeamer@h)
          -- (1.25*\sjtubeamer@h,0)
          -- (0.85*\sjtubeamer@h,-0.3*\sjtubeamer@h)
          -- (0.85*\sjtubeamer@h,-0.5*\sjtubeamer@h)
          -- (-0.85*\sjtubeamer@h,-0.5*\sjtubeamer@h)
          -- (-0.85*\sjtubeamer@h,-0.3*\sjtubeamer@h) -- cycle;
    \end{tikzpicture} 
  }
}
%    \end{macrocode}
% Unlike \verb"\highlight" to make use of \verb"\colorbox" from \verb"xcolor".
% \verb"\stamptext" has to use Ti\emph{k}Z for drawing the vi shape. And the VI
% rules that the shape could not be resized to a different aspect ratio.
% So the only available mode is scaling.
%
%  The tradeoff is that the text length has to be limited.
% \end{macro}
%
% \begin{macro}{\sjtubeamer@compatible}
% For \TeX Live 2018 and even older,
% it is \emph{not} compatible to use the
% patterns.meta library for making
% user-defined patterns.
% And fading is not available for caching.
% Please consider
% \verb"\def\sjtubeamer@compatible{false}"
% to match the following condition
% checking.
%
% Remember to use \verb"\makeatletter"
% and \verb"\makeatother" in \LaTeX{}.
%    \begin{macrocode}
\def\sjtubeamer@compatible@false{false}
%    \end{macrocode}
% We didn't make it as an option since it will break the hierarchical structure of
% option definition. This is the bottom level of all style files, no advanced
% methods are provided in this layer.
% \end{macro}
%
% \begin{macro}{stamp}
%	Make a stamp array.
%
% Use option
% \verb"[pattern={stamp[size=8pt,xshift=4pt,yshift=4pt]}]"
% on TikZ fill element.
%    \begin{macrocode}
\ifx\sjtubeamer@compatible\sjtubeamer@compatible@false
\else
  \usetikzlibrary{patterns.meta}
  \tikzdeclarepattern{
    name=stamp,
    parameters={
        \pgfkeysvalueof{/pgf/pattern keys/size},
        \pgfkeysvalueof{/pgf/pattern keys/xshift},
        \pgfkeysvalueof{/pgf/pattern keys/yshift},
      },
    defaults={
        size/.initial = 5pt,
        xshift/.initial = 0pt,
        yshift/.initial = 0pt,
      },
    bottom left={(
        -0.5*\pgfkeysvalueof{/pgf/pattern keys/size}
        +\pgfkeysvalueof{/pgf/pattern keys/xshift},
        -0.4*\pgfkeysvalueof{/pgf/pattern keys/size}
        +\pgfkeysvalueof{/pgf/pattern keys/yshift}
        )},
    top right={(
        0.5*\pgfkeysvalueof{/pgf/pattern keys/size}
        +\pgfkeysvalueof{/pgf/pattern keys/xshift},
        0.4*\pgfkeysvalueof{/pgf/pattern keys/size}
        +\pgfkeysvalueof{/pgf/pattern keys/yshift}
        )},
    tile size={(
        \pgfkeysvalueof{/pgf/pattern keys/size},
        0.8*\pgfkeysvalueof{/pgf/pattern keys/size}
        )},
    code={
        \def\sjtubeamer@s{\pgfkeysvalueof{/pgf/pattern keys/size}}%
        \tikzset{x=0.5*\sjtubeamer@s,y=0.2*\sjtubeamer@s}
        \fill[xshift=\pgfkeysvalueof{/pgf/pattern keys/xshift},
          yshift=\pgfkeysvalueof{/pgf/pattern keys/yshift}]
        (-0.25*\sjtubeamer@s,0)
        -- (-0.17*\sjtubeamer@s,0.06*\sjtubeamer@s)
        -- (-0.17*\sjtubeamer@s,0.1*\sjtubeamer@s)
        -- (0.17*\sjtubeamer@s,0.1*\sjtubeamer@s)
        -- (0.17*\sjtubeamer@s,0.06*\sjtubeamer@s)
        -- (0.25*\sjtubeamer@s,0)
        -- (0.17*\sjtubeamer@s,-0.06*\sjtubeamer@s)
        -- (0.17*\sjtubeamer@s,-0.1*\sjtubeamer@s)
        -- (-0.17*\sjtubeamer@s,-0.1*\sjtubeamer@s)
        -- (-0.17*\sjtubeamer@s,-0.06*\sjtubeamer@s) -- cycle;
      }
  }
\fi
%    \end{macrocode}
% Avoid calling macros in code section for performance reasons.
%
% The newest version of TikZ provides the interface to user-define a pattern.
% Obeying compatibility philosophy, use \verb"\pgfkeyvalueof" interface to get
% parameters in a standard way. The unit is first tested in a standalone file
% and previewed by TikZEdt.
% \end{macro}
%
% \begin{macro}{\stamparray}
% Create the stamp array in the TikZ
% environment.
%
% The first parameter is the pattern size.
%
% The second parameter is the starting
% point. Formatted in \verb"(0,0)".
%
% The third parameter is the ending point.
% Formatted in \verb"(0,0)".
%    \begin{macrocode}
\ifx\sjtubeamer@compatible\sjtubeamer@compatible@false
  \providecommand{\stamparray}[3]{}
\else
  \providecommand{\stamparray}[3]{
    % #1: pattern size
    % #2: starting point
    % #3: ending point
    \usebeamercolor{palette primary}
    \fill [pattern={stamp[size=#1]},
      pattern color=bg!50!fg] #2 rectangle #3;
    \def\sjtubeamer@s{#1}%
    \pgfmathparse{0.5*\sjtubeamer@s}\let\xs=\pgfmathresult%
    \pgfmathparse{-0.4*\sjtubeamer@s}\let\ys=\pgfmathresult%
    \fill [pattern={stamp[size=#1,xshift=\xs, yshift=\ys]},
      pattern color=bg!50!fg] #2 rectangle #3;
  }
\fi
%    \end{macrocode}
% NOTICE: \TeX{} is not good at handling parameters. Always remember to store it
% into a temporary variable. Register \verb"\pgfmathresult" will store the result
% of \verb"\pgfmathparse".
% \end{macro}
%
% \begin{macro}{stampline}
% A decoration to make a loop stampline.
%
% Use option to draw the stampline on TikZ
% draw element
%
% \verb"[decoration=stampline, segment length=1cm, decorate]".
%    \begin{macrocode}
\pgfdeclaredecoration{stampline}{initial}
{
  \state{initial}[
    width=\pgfdecorationsegmentlength,
    auto corner on length=\pgfdecorationsegmentlength]
  {
    \def\sjtubeamer@l{\pgfdecorationsegmentlength}%
    \pgfpathlineto{\pgfpoint{0.25*\sjtubeamer@l}{0pt}}
    \pgfpathlineto{\pgfpoint{0.33*\sjtubeamer@l}{0.06*\sjtubeamer@l}}
    \pgfpathlineto{\pgfpoint{0.33*\sjtubeamer@l}{0.1*\sjtubeamer@l}}
    \pgfpathlineto{\pgfpoint{0.67*\sjtubeamer@l}{0.1*\sjtubeamer@l}}
    \pgfpathlineto{\pgfpoint{0.67*\sjtubeamer@l}{0.06*\sjtubeamer@l}}
    \pgfpathlineto{\pgfpoint{0.75*\sjtubeamer@l}{0pt}}
    \pgfpathlineto{\pgfpoint{\sjtubeamer@l}{0pt}}
  }
  \state{final}
  {
    \pgfpathlineto{\pgfpointdecoratedpathlast}
  }
}
%    \end{macrocode}
% NOTICE: that \verb"auto corner on length" is open to avoid spikes where the
% state hasn't meet \verb"final" yet.
% \end{macro}
%
%
% \iffalse
%</package>
% \fi
%
% \Finale
\endinput
